/********************************************************************************
 *      Copyright:  (C) 2025 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  net_client.hpp
 *    Description:  This file 
 *
 *        Version:  1.0.0(29/09/25)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "29/09/25 15:54:49"
 *                 
 ********************************************************************************/

#ifndef _NET_CLIENT_H_
#define _NET_CLIENT_H_

#include <iostream>
#include <string>
#include <stdexcept>
#include <cstring>
#include <vector>

#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/tcp.h>
#include <errno.h>

namespace IotClient {

class TcpClient
{
public:
    TcpClient(const std::string& serv_ip, int port);

    ~TcpClient(); //析构函数，自动关闭socket连接

    void connectServer();

    void closeConnection();

    bool isConnected();

    int sendPacked(const std::vector<uint8_t>& data);

private:
    std::string servip_;
    int port_;
    int fd_ = -1;
    bool is_connected_ = false;

    //阻止拷贝构造（TcpClient client2 = client1）
    //如果不组织，client1/2将会拥有同一个fd，当其中一个对象被析构时，它会调用close（fd），导致另一个持有的fd变为无效
    //但它自己不知道，从而引发程序错误甚至崩溃
    //=delete：告诉编译器不要为这个类生成这个默认函数，并且如果有人试图调用这个函数，在编译时就报错
    TcpClient(const TcpClient&) = delete;
    //阻止拷贝赋值（将一个已存在的TcpClient对象赋值给另一个已存在的对象）
    //与拷贝构造函数一样，是避免两个对象共享同一个底层资源，从而避免双重释放的问题
    TcpClient& operator=(const TcpClient&) = delete;

    bool checkTcpState();
};

}

#endif
